package com.trailwalker.mediaplayer.customView;

import com.trailwalker.JavaUtils.log.LogUtils;
import com.trailwalker.javafx.utils.image.ImageUtils;
import com.trailwalker.javafx.utils.resource.ResourceUtils;
import com.trailwalker.javafx.utils.style.AdaptUtils;
import com.trailwalker.mediaplayer.service.Player;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.media.MediaPlayer;
import javafx.util.Duration;

/**
 * @author Trailwalker
 * @create 2021-09-06 0:35
 */
public class MediaBar extends HBox {

    private static final String TAG = MediaBar.class.getSimpleName();

    private Config mConfig;
    private AdaptUtils mAdaptUtils;
    private HBox mHbRoot;
    private HBox mBtnPrev;
    private HBox mBtnPlay;
    private HBox mBtnNext;
    private Slider mProgressSlider;
    private Label mLblCurrentTime;
    private Label mLblTotalTime;
    private Label mLblVolume;
    private Slider mVolumeSlider;
    private Slider mBalanceSlider;
    private Label mLblPlayMode;

    private MediaBar() {
        super();
    }

    public void setConfig(Config config) {
        mConfig = config;
    }

    public void init() {
        initLoad();
        initView();
        initData();
        initListener();
    }

    private void initListener() {

        if (mBtnPlay != null) {
            mBtnPlay.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    if (event.getButton().equals(MouseButton.PRIMARY)) {
                        mConfig.player.play();
                    }
                }
            });
        }

        if (mBtnPrev != null) {
            mBtnPrev.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    if (event.getButton().equals(MouseButton.PRIMARY)) {
                        mConfig.player.playPrev();
                    }
                }
            });
        }

        if (mBtnNext != null) {
            mBtnNext.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    if (event.getButton().equals(MouseButton.PRIMARY)) {
                        mConfig.player.playNext();
                    }
                }
            });
        }

        if (mProgressSlider != null) {
            mProgressSlider.setOnMousePressed(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    if (mConfig.player != null) {
                        mConfig.player.unbindCurrentTime();
                    }
                }
            });
            mProgressSlider.setOnMouseReleased(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    if (mConfig.player != null) {
                        mConfig.player.bindCurrentTime(mProgressSlider.valueProperty());
                        mConfig.player.seek(Duration.seconds(mProgressSlider.getValue()));
                    }
                }
            });
        }

        mConfig.player.setOnReady(new Runnable() {
            @Override
            public void run() {
                Duration mediaDuration = mConfig.player.getCurrentMedia().getDuration();
                mProgressSlider.setMin(0);
                double seconds = mediaDuration.toSeconds();
                mProgressSlider.setMax(seconds);
                mProgressSlider.setValue(mConfig.player.getCurrentTime().toSeconds());
                mLblTotalTime.setText(getShowTime((int) seconds));
            }
        });

        mConfig.player.addCurrentTimeListener(new ChangeListener<Duration>() {
            @Override
            public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
                int totalSeconds = (int) newValue.toSeconds();
                String showTime = getShowTime(totalSeconds);
                mLblCurrentTime.setText(showTime);
            }
        });

        mConfig.player.addStatusListener(new ChangeListener<MediaPlayer.Status>() {
            @Override
            public void changed(ObservableValue<? extends MediaPlayer.Status> observable, MediaPlayer.Status oldValue, MediaPlayer.Status newValue) {
                LogUtils.log(TAG, newValue.name());
                ImageView ivBtn = (ImageView) mBtnPlay.lookup("#ivBtn");
                if (newValue.equals(MediaPlayer.Status.PLAYING)) {
                    ivBtn.setImage(new Image(ResourceUtils.getImage(this,"pause_press.png")));
                } else {
                    ivBtn.setImage(new Image(ResourceUtils.getImage(this,"play_press.png")));
                }
                if (mBtnPlay != null) {
                    mBtnPlay.setOnMouseClicked(new EventHandler<MouseEvent>() {
                        @Override
                        public void handle(MouseEvent event) {
                            if (event.getButton().equals(MouseButton.PRIMARY)) {
                                if (newValue.equals(MediaPlayer.Status.PLAYING)) {
                                    mConfig.player.pause();
                                } else {
                                    mConfig.player.play();
                                }
                            }
                        }
                    });
                }
            }
        });

        mConfig.player.addPlayModeListener(new ChangeListener<Player.PlayMode>() {
            @Override
            public void changed(ObservableValue<? extends Player.PlayMode> observable, Player.PlayMode oldValue, Player.PlayMode newValue) {
                mLblPlayMode.setText(newValue.getMessage());
            }
        });

        if (mLblPlayMode != null) {
            mLblPlayMode.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    if (event.getButton().equals(MouseButton.PRIMARY)) {
                        mConfig.player.changePlayMode();
                    }
                }
            });
        }
    }

    public String getShowTime(int totalSeconds) {
        int minutes = totalSeconds / 60;
        String strMinutes = "";
        if (minutes < 10) {
            strMinutes += "0";
        }
        strMinutes += minutes;
        int seconds = totalSeconds % 60;
        String strSeconds = "";
        if (seconds < 10) {
            strSeconds += "0";
        }
        strSeconds += seconds;
        return strMinutes + ":" + strSeconds;
    }

    private void initData() {
        mConfig.player.bindCurrentTime(mProgressSlider.valueProperty());
        mConfig.player.bindBalance(mBalanceSlider.valueProperty());
        mConfig.player.bindVolume(mVolumeSlider.valueProperty());
    }

    private void initView() {
        mHbRoot = this;
        mHbRoot.getStyleClass().add("media_bar_background");
        mHbRoot.setAlignment(Pos.CENTER);
        mAdaptUtils.setScalePaddingLeftAndRight(this, 20);
        mAdaptUtils.setScalePaddingTopAndBottom(this, 10);

        mBtnPrev = getButton(30, 20, 15, "prev_normal.png", "prev_press.png");
        mBtnPlay = getButton(30, 20, 15, "play_press.png", null);
        mBtnNext = getButton(30, 20, 15, "next_normal.png", "next_press.png");

        mLblCurrentTime = new Label();
        mHbRoot.getChildren().add(mLblCurrentTime);
        mLblCurrentTime.setText("00:00");
        mLblCurrentTime.getStyleClass().add("lbl_text_color");
        mAdaptUtils.setScaleTextSize(mLblCurrentTime, 15);
        HBox.setMargin(mLblCurrentTime, mAdaptUtils.getMarginRight(15, HBox.getMargin(mLblCurrentTime)));

        mProgressSlider = new Slider();
        mHbRoot.getChildren().add(mProgressSlider);
        HBox.setHgrow(mProgressSlider, Priority.ALWAYS);
        HBox.setMargin(mProgressSlider, mAdaptUtils.getMarginRight(15, HBox.getMargin(mProgressSlider)));

        mLblTotalTime = new Label();
        mHbRoot.getChildren().add(mLblTotalTime);
        mLblTotalTime.setText("00:00");
        mLblTotalTime.getStyleClass().add("lbl_text_color");
        mAdaptUtils.setScaleTextSize(mLblTotalTime, 15);
        HBox.setMargin(mLblTotalTime, mAdaptUtils.getMarginRight(15, HBox.getMargin(mLblTotalTime)));

        mLblVolume = new Label();
        mHbRoot.getChildren().add(mLblVolume);
        mLblVolume.setText("音量");
        mLblVolume.getStyleClass().add("lbl_text_color");
        mAdaptUtils.setScaleTextSize(mLblVolume, 15);
        HBox.setMargin(mLblVolume, mAdaptUtils.getMarginRight(15, HBox.getMargin(mLblVolume)));

        mVolumeSlider = new Slider();
        mHbRoot.getChildren().add(mVolumeSlider);
        mVolumeSlider.setMin(0);
        mVolumeSlider.setMax(1);
        mVolumeSlider.setValue(0.3);
        mAdaptUtils.setScaleWidth(mVolumeSlider, 100);
        HBox.setMargin(mVolumeSlider, mAdaptUtils.getMarginRight(15, HBox.getMargin(mVolumeSlider)));


        mBalanceSlider = new Slider();
        mHbRoot.getChildren().add(mBalanceSlider);
        mBalanceSlider.setMin(-1);
        mBalanceSlider.setMax(1);
        mBalanceSlider.setValue(0);
        mAdaptUtils.setScaleWidth(mBalanceSlider, 100);
        HBox.setMargin(mBalanceSlider, mAdaptUtils.getMarginRight(15, HBox.getMargin(mBalanceSlider)));

        mLblPlayMode = new Label();
        mHbRoot.getChildren().add(mLblPlayMode);
        mLblPlayMode.setText(Player.PlayMode.RANDOM.getMessage());
        mLblPlayMode.getStyleClass().add("lbl_text_color");
        mLblPlayMode.setCursor(Cursor.HAND);
        mAdaptUtils.setScaleTextSize(mLblPlayMode, 15);
        mAdaptUtils.setScaleWidth(mLblPlayMode, 80);
        mLblCurrentTime.setAlignment(Pos.CENTER);
        HBox.setMargin(mLblPlayMode, mAdaptUtils.getMarginRight(15, HBox.getMargin(mLblPlayMode)));

    }

    private HBox getButton(int containerSize, int btnSize, int marginRight, String imageResourcePath, String hoverImageResourcePath) {
        HBox hbContainer = new HBox();
        mHbRoot.getChildren().add(hbContainer);
        HBox.setMargin(hbContainer, mAdaptUtils.getMarginRight(marginRight, HBox.getMargin(hbContainer)));
        mAdaptUtils.setScaleSize(hbContainer, containerSize);
        mAdaptUtils.setBackgroundRadius(hbContainer, containerSize / 2);
        mAdaptUtils.setBorderRadius(hbContainer, containerSize / 2);
        hbContainer.setAlignment(Pos.CENTER);
        hbContainer.getStyleClass().add("media_bar_button_background");

        ImageView iv = ImageUtils.getImageView(this,btnSize, imageResourcePath, hoverImageResourcePath);
        iv.setId("ivBtn");
        hbContainer.getChildren().add(iv);

        return hbContainer;
    }

    private void initLoad() {
        mAdaptUtils = AdaptUtils.getInstance();
    }

    public static class Builder {

        private final Config mConfig;

        public Builder(Player player) {
            mConfig = new Config();
            mConfig.player = player;
        }

        public MediaBar build() {
            MediaBar mediaBar = new MediaBar();
            mediaBar.setConfig(mConfig);
            mediaBar.init();
            return mediaBar;
        }
    }

    public static class Config {
        public Player player;
    }
}
